package com.mall.mina.core;

import com.mall.mina.config.CustomPack;
import com.mall.mina.config.MinaServer;
import com.mall.mina.config.MinaServerHandler;
import com.mall.mina.util.AgreementConstant;
import com.mall.mina.util.AgreementUtil;
import com.mall.mina.util.CrcUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.Locale;

@Slf4j
@Component
public class LockTemplate {

    MinaServerHandler serverHandler = new MinaServerHandler();

    /**
     * 开启服务，进行数据监听
     * @param port 端口号
     * @return
     * @throws
     */
    public boolean init(int port){
        MinaServer server = new MinaServer();
        boolean init = server.init(port);
        return init;
    }



    /**
     * 下发指纹数据
     * @param deviceId              设备id
     * @param lockId           锁id
     * @param accountId             用户id
     * @param fingerprint      指纹
     * @return
     * @throws Exception
     */
    public synchronized LockResult setFingerprint(String deviceId,Integer lockId,String accountId,String fingerprint){
        if (AgreementUtil.checkAgreement(deviceId,accountId,fingerprint)) {
            return LockResult.msg("参数异常");
        }
        accountId = accountId.trim();
        deviceId = deviceId.trim();
        if(deviceId.length() != 8 ||AgreementUtil.checkAccountId(accountId) || AgreementUtil.checkLock(lockId)){
            return LockResult.msg("参数异常");
        }
        byte[] fingerprintBytes = AgreementUtil.hexStringToBytes(fingerprint);
        byte lockIdBytes = lockId.byteValue();
        if (fingerprintBytes == null ){
            return LockResult.msg("参数异常");
        }

        byte[] deviceIdBytes = AgreementUtil.hexStringToBytes(deviceId);
        byte[] accountIdBytes = AgreementUtil.hexStringToBytes(String.format("%04d", Integer.valueOf(accountId)));

        int frameLen = 1 + deviceIdBytes.length + 1 + accountIdBytes.length + fingerprintBytes.length + 2;
        byte[] frameLenBytes = AgreementUtil.shortToByteArray((short) frameLen);
        byte[] args = {frameLenBytes[0],frameLenBytes[1], AgreementConstant.FINGERPRINT_SET,deviceIdBytes[0],deviceIdBytes[1],deviceIdBytes[2],deviceIdBytes[3],lockIdBytes, accountIdBytes[0],accountIdBytes[1]};
        byte[] agreement = AgreementUtil.assembleAgreement(args, fingerprintBytes);
        byte[] crc16 = CrcUtils.crc16ab(agreement);
        byte[] args2 = {AgreementConstant.FINGERPRINT_SET,deviceIdBytes[0],deviceIdBytes[1],deviceIdBytes[2],deviceIdBytes[3],lockIdBytes, accountIdBytes[0],accountIdBytes[1]};
        byte[] content = AgreementUtil.assembleAgreement(args2, fingerprintBytes);
        CustomPack pack = new CustomPack();
        pack.setLen(frameLenBytes);
        pack.setContent(content);
        pack.setCrc(crc16);
        byte[] send = serverHandler.send(deviceIdBytes, lockIdBytes, pack);
        if (send == null){
            return LockResult.msg("网络连接异常,请重试！");
        }
        if (send[0] == AgreementConstant.DATA_ERROR){
            return LockResult.msg("指令异常！");
        }
        //下发指纹状态(1:成功;0:失败)
        String status = AgreementUtil.byteToInt(send[8]).toString();
        if("1".equals(status)){
            LockResult result = new LockResult();
            result.setCode(send[0] + "");
            result.setMessage("下发指纹数据");
            LockMessage lock = new LockMessage();
            deviceId = AgreementUtil.byteArrayToHexString(new byte[]{send[1],send[2],send[3],send[4]});
            lock.setIp(serverHandler.findIPByDeviceId(deviceId));
            lock.setDeviceId(deviceId);
            lock.setLockId(AgreementUtil.byteToInt(send[5]).toString());
            lock.setAccountId(Integer.valueOf(AgreementUtil.byteArrayToHexString(new byte[]{send[6],send[7]})).toString());;
            lock.setFingerprintStatus(AgreementUtil.byteToInt(send[8]).toString());
            result.setObj(lock);
            return result;
        }else{
            return LockResult.msg("下发失败！");
        }
    }

    /**
     * 获取指纹数据
     * @param deviceId              设备id
     * @param lockId           锁id
     * @param accountId             用户id
     */
    public synchronized LockResult getFingerprint(String deviceId,Integer lockId,String accountId){
        if (AgreementUtil.checkAgreement(deviceId,accountId)) {
            return LockResult.msg("参数异常");
        }
        accountId = accountId.trim();
        deviceId = deviceId.trim();
        if(deviceId.length() != 8 || AgreementUtil.checkAccountId(accountId) || AgreementUtil.checkLock(lockId)){
            return LockResult.msg("参数异常");
        }
        byte lockIdBytes = lockId.byteValue();
        byte[] deviceIdBytes = AgreementUtil.hexStringToBytes(deviceId);
        byte[] accountIdBytes = AgreementUtil.hexStringToBytes(String.format("%04d", Integer.valueOf(accountId)));

        int frameLen = 1 + deviceIdBytes.length + 1 + accountIdBytes.length + 2;
        byte[] frameLenBytes = AgreementUtil.shortToByteArray((short) frameLen);
        byte[] args = {frameLenBytes[0],frameLenBytes[1], AgreementConstant.FINGERPRINT_GET,deviceIdBytes[0],deviceIdBytes[1],deviceIdBytes[2],deviceIdBytes[3],lockIdBytes, accountIdBytes[0],accountIdBytes[1]};
        byte[] crc16 = CrcUtils.crc16ab(args);
        byte[] content = {AgreementConstant.FINGERPRINT_GET,deviceIdBytes[0],deviceIdBytes[1],deviceIdBytes[2],deviceIdBytes[3],lockIdBytes, accountIdBytes[0],accountIdBytes[1]};
        CustomPack pack = new CustomPack();
        pack.setLen(frameLenBytes);
        pack.setContent(content);
        pack.setCrc(crc16);
        byte[] send = serverHandler.send(deviceIdBytes, lockIdBytes, pack);
        if (send == null){
            return LockResult.msg("网络连接异常,请重试！");
        }
        if (send[0] == AgreementConstant.DATA_ERROR){
            return LockResult.msg("指令异常！");
        }
        LockResult result = new LockResult();
        result.setCode(send[0] + "");
        result.setMessage("获取指纹数据");
        LockMessage lock = new LockMessage();
        deviceId = AgreementUtil.byteArrayToHexString(new byte[]{send[1],send[2],send[3],send[4]});
        lock.setIp(serverHandler.findIPByDeviceId(deviceId));
        lock.setDeviceId(deviceId);
        lock.setLockId(AgreementUtil.byteToInt(send[5]).toString());
        lock.setAccountId(Integer.valueOf(AgreementUtil.byteArrayToHexString(new byte[]{send[6],send[7]})).toString());;
        StringBuffer f = new StringBuffer();
        for (int i = 8,j = 0; i < send.length; i++) {
            String hexString = Integer.toHexString(send[i] & 0xFF).toUpperCase(Locale.ROOT);
            if (hexString.length() < 2){
                hexString = "0" + hexString;
            }
            f.append(hexString);
        }
        lock.setFingerprint(f.toString());
        result.setObj(lock);
        return result;
    }

}